#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include "lua.h"
#include "lauxlib.h"

// redis相关
#include "../fmacros.h"
#include "../config.h"
#include "../dict.h"
#include "../sds.h"
#include "../zmalloc.h"

static dict * myUsersDict = NULL;

unsigned int dictKeyHash(const void *keyp) {
    unsigned long key = (unsigned long)keyp;
    key = dictGenHashFunction(&key,sizeof(key));
    key += ~(key << 15);
    key ^=  (key >> 10);
    key +=  (key << 3);
    key ^=  (key >> 6);
    key += ~(key << 11);
    key ^=  (key >> 16);
    return key;
}

int dictKeyCompare(void *privdata, const void *key1, const void *key2) {
    unsigned long k1 = (unsigned long)key1;
    unsigned long k2 = (unsigned long)key2;
    return k1 == k2;
}

static dictType hash_type = {
    dictKeyHash,                   /* hash function */
    NULL,                          /* key dup */
    NULL,                          /* val dup */
    dictKeyCompare,                /* key compare */
    NULL,                          /* key destructor */
    NULL                           /* val destructor */
};

static int lua_f_set( lua_State *L )
{
    unsigned long uid = luaL_checkinteger(L, 1);
    int kid = luaL_checkinteger(L, 2);
    dictEntry *entry = dictAddRaw(myUsersDict,(void*)uid,NULL);
    if(entry)
    {
        dictSetSignedIntegerVal(entry,kid);
    }
    return 0;
}

static int lua_f_get( lua_State *L )
{
	unsigned long uid = luaL_checkinteger(L, 1);
    dictEntry * he = dictFind(myUsersDict, (void * )uid);
	if( NULL == he)
	{
		lua_pushnil(L);
		return 1;
	}
	int value = dictGetSignedIntegerVal(he);
    lua_pushinteger(L,value);
    return 1;
}

static int lua_f_find( lua_State *L )
{
	unsigned long uid = luaL_checkinteger(L, 1);
    dictEntry * he = dictFind(myUsersDict, (void * )uid);
	if( NULL == he)
		lua_pushboolean(L,0);
	else
		lua_pushboolean(L,1);
    return 1;
}

static int lua_f_delete( lua_State *L )
{
    unsigned long uid = luaL_checkinteger(L, 1);
    int ret = dictDelete(myUsersDict, (void * )uid);
    lua_pushinteger(L,ret);
    return 1;
}

static int lua_f_release( lua_State *L )
{
	dictRelease(myUsersDict);
	myUsersDict = NULL;
	return 0;
}

LUALIB_API int 
luaopen_resharedUsers( lua_State *L )
{
    luaL_checkversion(L);

    luaL_Reg l[] = {
        {"set",lua_f_set},
        {"get",lua_f_get},
        {"find",lua_f_find},
        {"delete",lua_f_delete},
        {"release",lua_f_release},
        {NULL, NULL}
    };
    luaL_newlib(L,l);
	
    if( NULL == myUsersDict)
        myUsersDict = dictCreate(&hash_type, NULL);

    return 1;
}
